package com.ruoyi.order.service.impl;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.app.dto.*;
import com.ruoyi.app.param.ChangeShopCartParam;
import com.ruoyi.app.param.OrderItemParam;
import com.ruoyi.app.param.ShopCartParam;
import com.ruoyi.app.util.CacheManagerUtil;
import com.ruoyi.common.utils.Arith;
import com.ruoyi.order.mapper.BasketMapper;
import com.ruoyi.outlet.domain.TzShopDetail;
import com.ruoyi.outlet.service.ITzShopDetailService;
import com.ruoyi.product.domain.Product;
import com.ruoyi.product.domain.Sku;
import com.ruoyi.product.mapper.ProductMapper;
import com.ruoyi.product.service.IProductService;
import com.ruoyi.product.service.ISkuService;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import com.ruoyi.order.domain.Basket;
import com.ruoyi.order.service.IBasketService;

import javax.annotation.Resource;

/**
 * 购物车Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-14
 */
@Service
public class BasketServiceImpl implements IBasketService {
    @Resource
    private BasketMapper basketMapper;
    @Autowired
    private IProductService productService;
    @Autowired
    private ISkuService skuService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private ITzShopDetailService shopDetailService;
    @Autowired
    private CacheManagerUtil cacheManagerUtil;


    /**
     * 查询购物车
     *
     * @param basketId 购物车主键
     * @return 购物车
     */
    @Override
    public Basket selectBasketByBasketId(Long basketId) {
        return basketMapper.selectBasketByBasketId(basketId);
    }

    /**
     * 查询购物车列表
     *
     * @param basket 购物车
     * @return 购物车
     */
    @Override
    public List<Basket> selectBasketList(Basket basket) {
        return basketMapper.selectBasketList(basket);
    }

    /**
     * 新增购物车
     *
     * @param basket 购物车
     * @return 结果
     */
    @Override
    public int insertBasket(Basket basket) {
        return basketMapper.insertBasket(basket);
    }

    /**
     * 修改购物车
     *
     * @param basket 购物车
     * @return 结果
     */
    @Override
    public int updateBasket(Basket basket) {
        return basketMapper.updateBasket(basket);
    }

    /**
     * 批量删除购物车
     *
     * @param basketIds 需要删除的购物车主键
     * @return 结果
     */
    @Override
    public int deleteBasketByBasketIds(Long[] basketIds) {
        return basketMapper.deleteBasketByBasketIds(basketIds);
    }

    /**
     * 删除购物车信息
     *
     * @param basketId 购物车主键
     * @return 结果
     */
    @Override
    public int deleteBasketByBasketId(Long basketId) {
        return basketMapper.deleteBasketByBasketId(basketId);
    }

    @Override
    public List<ShopCartItemDto> getShopCartItemsByOrderItems(List<Long> basketId, OrderItemParam orderItem, String userId) {
        if (orderItem == null && CollectionUtil.isEmpty(basketId)) {
            return Collections.emptyList();
        }

        // 当立即购买时，没有提交的订单是没有购物车信息的
        if (CollectionUtil.isEmpty(basketId) && orderItem != null) {

            Sku sku = skuService.getSkuBySkuId(orderItem.getSkuId());
            if (sku == null) {
                throw new RuntimeException("订单包含无法识别的商品");
            }
            Product prod = productService.getProductByProdId(orderItem.getProdId());
            if (prod == null) {
                throw new RuntimeException("订单包含无法识别的商品");
            }

            // 拿到购物车的所有item
            ShopCartItemDto shopCartItemDto = new ShopCartItemDto();
            shopCartItemDto.setBasketId(-1L);
            shopCartItemDto.setSkuId(orderItem.getSkuId());
            shopCartItemDto.setProdCount(orderItem.getProdCount());
            shopCartItemDto.setProdId(orderItem.getProdId());
            shopCartItemDto.setSkuName(sku.getSkuName());
            shopCartItemDto.setPic(StrUtil.isBlank(sku.getPic()) ? prod.getPic() : sku.getPic());
            shopCartItemDto.setProdName(sku.getProdName());
            shopCartItemDto.setProductTotalAmount(Arith.mul(sku.getPrice(), orderItem.getProdCount()));
            shopCartItemDto.setPrice(sku.getPrice());
            shopCartItemDto.setDistributionCardNo(orderItem.getDistributionCardNo());
            shopCartItemDto.setBasketDate(new Date());
            TzShopDetail shopDetail = shopDetailService.selectTzShopDetailByShopId(orderItem.getShopId());
            shopCartItemDto.setShopId(shopDetail.getShopId());
            shopCartItemDto.setShopName(shopDetail.getShopName());
            return Collections.singletonList(shopCartItemDto);
        }
        List<ShopCartItemDto> dbShopCartItems = null;

        // 返回购物车选择的商品信息
        return dbShopCartItems
                .stream()
                .filter(shopCartItemDto -> basketId.contains(shopCartItemDto.getBasketId()))
                .collect(Collectors.toList());
    }


    @Override
    public List<ShopCartDto> getShopCarts(List<ShopCartItemDto> shopCartItems) {
        // 根据店铺ID划分item
        Map<Long, List<ShopCartItemDto>> shopCartMap = shopCartItems.stream().collect(Collectors.groupingBy(ShopCartItemDto::getShopId));

        // 返回一个店铺的所有信息
        List<ShopCartDto> shopCartDtos = Lists.newArrayList();
        for (Long shopId : shopCartMap.keySet()) {
            System.err.println(shopCartMap);
            //获取店铺的所有商品项
            List<ShopCartItemDto> shopCartItemDtoList = shopCartMap.get(shopId);

            // 构建每个店铺的购物车信息
            ShopCartDto shopCart = new ShopCartDto();

            //店铺信息
            shopCart.setShopId(shopId);
            shopCart.setShopName(shopCartItemDtoList.get(0).getShopName());

            applicationContext.publishEvent(new ShopCartEvent(shopCart, shopCartItemDtoList));

            shopCartDtos.add(shopCart);
        }

        return shopCartDtos;
    }

    @Override
    public void updateBasketByShopCartParam(String userId, Map<Long, ShopCartParam> basketIdShopCartParamMap) {
        basketMapper.updateDiscountItemId(userId, basketIdShopCartParamMap);
    }

    @Override
    public List<ShopCartItemDto> getShopCartItems(String userId) {
        // 在这个类里面要调用这里的缓存信息，并没有使用aop，所以不使用注解
        List<ShopCartItemDto> shopCartItemDtoList = cacheManagerUtil.getCache("ShopCartItems", userId);
        if (shopCartItemDtoList != null) {
            return shopCartItemDtoList;
        }
        shopCartItemDtoList = basketMapper.getShopCartItems(userId);
        for (ShopCartItemDto shopCartItemDto : shopCartItemDtoList) {
            shopCartItemDto.setProductTotalAmount(Arith.mul(shopCartItemDto.getProdCount(), shopCartItemDto.getPrice()));
        }
        cacheManagerUtil.putCache("ShopCartItems", userId, shopCartItemDtoList);
        return shopCartItemDtoList;
    }

    @Override
    public void deleteShopCartItemsByBasketIds(String userId, List<Long> basketIds) {
        basketMapper.deleteShopCartItemsByBasketIds(userId, basketIds);
    }

    @Override
    public void deleteAllShopCartItems(String userId) {
        basketMapper.deleteAllShopCartItems(userId);
    }

    @Override
    public void updateShopCartItem(Basket basket) {
        basketMapper.updateBasket(basket);
    }

    @Override
    public void addShopCartItem(ChangeShopCartParam param, String userId) {
        Basket basket = new Basket();
        basket.setBasketCount(Long.valueOf(param.getCount()));
        basket.setBasketDate(new Date());
        basket.setProdId(param.getProdId());
        basket.setShopId(param.getShopId());
        basket.setUserId(userId);
        basket.setSkuId(param.getSkuId());
        basket.setDistributionCardNo(param.getDistributionCardNo());
        basketMapper.insertBasket(basket);
    }

    @Override
    public List<ShopCartItemDto> getShopCartExpiryItems(String userId) {
        return basketMapper.getShopCartExpiryItems(userId);
    }

    @Override
    public void cleanExpiryProdList(String userId) {
        basketMapper.cleanExpiryProdList(userId);
    }

}
